﻿using System.ComponentModel;

namespace CyberConnect.Insteon
{
    /// <summary>
    /// Represents the configuration state of the PLM
    /// </summary>
    [ImmutableObject(true)]
    public class PlmConfiguration : IMessage
    {
        private readonly byte _Configuration;

        /// <summary>
        /// Disables automatic linking when the user pushes and holds the PLM's SET button.
        /// </summary>
        public bool DisableAutoLink { get { return (this._Configuration & 0x80) > 0; } }

        /// <summary>
        /// Puts the PLM into MonitorMode allowing eaves dropping on messages not sent to the PLM.
        /// </summary>
        public bool MonitorMode { get { return (this._Configuration & 0x40) > 0; } }

        /// <summary>
        /// Disables automatic LED operation by the PLM. Allows manual control of the LED via <see cref="PlmLinc">PlmLinc</see>
        /// </summary>
        public bool DisableAutoLed { get { return (this._Configuration & 0x20) > 0; } }

        /// <summary>
        /// Disables the Deadman feature allowing the API to delay more than 240ms in sending bytes of a message. (This is NOT recommended.)
        /// </summary>
        public bool DisableDeadman { get { return (this._Configuration & 0x10) > 0; } }

        internal PlmConfiguration(byte configuration)
        {
            this._Configuration = (byte)(configuration & 0xF0);
        }

        /// <summary>
        /// Creates a configuration object for the PLM
        /// </summary>
        /// <param name="disableAutoLink">Disables automatic linking when the user pushes and holds the PLM's SET button.</param>
        /// <param name="monitorMode">Puts the PLM into MonitorMode allowing eaves dropping on messages not sent to the PLM.</param>
        /// <param name="disableAutoLed">Disables automatic LED operation by the PLM. Allows manual control of the LED via <see cref="PlmLinc">PlmLinc</see></param>
        /// <param name="disableDeadman">Disable the Deadman feature allowing the API to delay more than 240ms in sending bytes of a message. (This is NOT recommended.)</param>
        public PlmConfiguration(bool disableAutoLink, bool monitorMode, bool disableAutoLed, bool disableDeadman)
        {
            this._Configuration = (byte)((disableAutoLink ? 128 : 0) + (monitorMode ? 64 : 0) + (disableAutoLed ? 32 : 0) + (disableDeadman ? 16 : 0));
        }

        internal static byte[] GetQueryBytes()
        {
            return new byte[] { 2, (byte)PlmCommand.GetPlmConfiguration };
        }

        /// <summary>
        /// Breaks the PlmConfiguration into a byte array that the PLM understands.
        /// </summary>
        /// <returns>A byte array that the PLM understands</returns>
        public byte[] ToBytes()
        {
            return new byte[] { 2, (byte)PlmCommand.SetPlmConfiguration, this._Configuration };
        }
    }
}